#ifndef EASY_CAR_UI_RENDER_ENGINE_VULKAN_PHYSICAL_DEVICE_H_
#define EASY_CAR_UI_RENDER_ENGINE_VULKAN_PHYSICAL_DEVICE_H_

#include <vulkan/vulkan.h>

#include <map>
#include <vector>
#include <optional>
#include <memory>
#include <string>

namespace namespace_easy_car_ui
{

class PhysicalDevice
{
public:
using Ptr = std::shared_ptr<PhysicalDevice>;

    PhysicalDevice() = delete;
    PhysicalDevice(const PhysicalDevice&) = delete;
    PhysicalDevice(const PhysicalDevice&&) = delete;
    PhysicalDevice& operator=(const PhysicalDevice&) = delete;
    PhysicalDevice& operator=(const PhysicalDevice&&) = delete;

    PhysicalDevice(VkPhysicalDevice physicalDevice);
    ~PhysicalDevice();

    bool IsGraphicAbility();
    uint32_t GetScore();
    VkPhysicalDevice GetHandle();
    uint32_t GetGraphicQueueFamilyIndex();
    std::string GetName();
    std::string GetSupportedVulkanVersion();
    uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);

private:
    void GetQueueFamilyProperties();
    void FindGraphicQueueFamily();
    void CalcSore();

private:
    VkPhysicalDevice m_physicalDevice {};
    VkPhysicalDeviceProperties m_physicalDeviceProperties {};
    std::vector<VkQueueFamilyProperties> m_queueFamilyPropertiesVec{};
    std::optional<uint32_t> m_graphicQueueFamilyIndex{std::nullopt};
    uint32_t m_score{0};
};

} /* namespace_easy_car_ui */

#endif /*EASY_CAR_UI_RENDER_ENGINE_VULKAN_PHYSICAL_DEVICE_H_*/